
import re
import zipfile
from StringIO import StringIO
from xml.etree import ElementTree
import mimetypes
from google.appengine.api import users
from ..library.BeautifulSoup import BeautifulSoup, Tag, NavigableString
from ..library import soupselect
from layeredcontent.handler.handlers import RequestHandler
from layeredcontent.model import *
from layeredcontent.xml import cssToXpath


class TemplateHandler(RequestHandler):
  
  urls = {
    '/lc/templates/': 'list',
    '/lc/templates/upload': {'get': 'upload', 'post': 'handle_upload'},
    '/lc/templates/:key': 'view',
    '/lc/templates/:key/preview': 'preview',
  }
  
  
  def view(self, key):
    template = Template.get(key)
    self.render_source(template.html)
  
  def preview(self, key):
    template = Template.get(key)
    self.render_source(template.html)

  def list(self):
    query = Template.all().order('-created')
    self.render('template-list.html', {'templates' : query.fetch(21)})

  def upload(self):
    self.render('template-upload.html')
  
  def handle_upload(self):
    stream = StringIO(self.request.get('template'))
    
    try:
      zip = zipfile.ZipFile(stream, 'r')
    except zipfile.BadZipfile:
      return self.user_error('Template Zip was not a valid zip file')
    
    validFile = re.compile(r'(^|/)[^./]+\.\w+$')
    files = zip.namelist()
    folder = files[0]
    folderLen = len(folder)
    files = map(lambda name:name[folderLen:], files)
    files = filter(lambda name:validFile.search(name) and name != 'template.xml' and name != 'template.html', files)
    
    htmlSource = zip.read(folder + 'template.html').replace('&copy;', '&#169;')
    xmlSource = zip.read(folder + 'template.xml')
    xml = ElementTree.ElementTree()
    xml.parse(StringIO(xmlSource))
    name = xml.findtext('title')
    
    results = Template.all().filter('name =', name).fetch(1)
    template = len(results) and results[0] or Template()
    template.html = htmlSource
    template.xml = xmlSource
    template.name = name
    template.author = xml.findtext('author/name')
    template.compiled = self.compile(BeautifulSoup(htmlSource), xml)
    template.put()
    
    domain = re.sub(r'^[^/]*//([^/:]+).*$', r'\1', self.request.url)
    for path in files:
      results = Resource.all().filter('domain =', domain).filter('path =', '/' + path).fetch(1)
      resource = len(results) and results[0] or Resource()
      content = zip.read(folder + path)
      if resource.path == '/' + path and resource.content == content:
        continue
      
      if resource.path != path:
        resource.domain = domain
        resource.path = '/' + path
        mime, encoding = mimetypes.guess_type(path)
        if mime:
          resource.mime = mime
      resource.author = users.get_current_user()
      resource.content = content
      resource.put()
    
    self.user_msg('Upload complete')
    self.redirect('/lc/templates/')
    
  
  def compile(self, html, xml):
    
    for field in xml.findall('fields/field'):
      elements = soupselect.select(html, field.get('path'))
      if not elements: continue
      for element in elements:
        element.contents = []
        element.insert(0, NavigableString('{{%s}}' % field.get('name')))
      
    return html.prettify()
  
    














